
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>pymatgen.analysis.fragmenter &#8212; pymatgen 2020.7.3 documentation</title>
    <link rel="stylesheet" href="../../../_static/basic.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    <script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
    <script src="../../../_static/jquery.js"></script>
    <script src="../../../_static/underscore.js"></script>
    <script src="../../../_static/doctools.js"></script>
    <script src="../../../_static/language_data.js"></script>
    <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
 
<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-33990148-1']);
  _gaq.push(['_trackPageview']);
</script>

  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">pymatgen 2020.7.3 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../../pymatgen.html" accesskey="U">pymatgen</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">pymatgen.analysis.fragmenter</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
          <div class="body" role="main">
            
  <h1>Source code for pymatgen.analysis.fragmenter</h1><div class="highlight"><pre>
<span></span><span class="c1"># coding: utf-8</span>
<span class="c1"># Copyright (c) Pymatgen Development Team.</span>
<span class="c1"># Distributed under the terms of the MIT License.</span>

<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Perform fragmentation of molecules.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">copy</span>
<span class="kn">from</span> <span class="nn">monty.json</span> <span class="kn">import</span> <span class="n">MSONable</span>
<span class="kn">from</span> <span class="nn">pymatgen.analysis.graphs</span> <span class="kn">import</span> <span class="n">MoleculeGraph</span><span class="p">,</span> <span class="n">MolGraphSplitError</span>
<span class="kn">from</span> <span class="nn">pymatgen.analysis.local_env</span> <span class="kn">import</span> <span class="n">OpenBabelNN</span>
<span class="kn">from</span> <span class="nn">pymatgen.io.babel</span> <span class="kn">import</span> <span class="n">BabelMolAdaptor</span>

<span class="n">__author__</span> <span class="o">=</span> <span class="s2">&quot;Samuel Blau&quot;</span>
<span class="n">__copyright__</span> <span class="o">=</span> <span class="s2">&quot;Copyright 2018, The Materials Project&quot;</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;2.0&quot;</span>
<span class="n">__maintainer__</span> <span class="o">=</span> <span class="s2">&quot;Samuel Blau&quot;</span>
<span class="n">__email__</span> <span class="o">=</span> <span class="s2">&quot;samblau1@gmail.com&quot;</span>
<span class="n">__status__</span> <span class="o">=</span> <span class="s2">&quot;Beta&quot;</span>
<span class="n">__date__</span> <span class="o">=</span> <span class="s2">&quot;8/21/19&quot;</span>

<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>


<div class="viewcode-block" id="Fragmenter"><a class="viewcode-back" href="../../../pymatgen.analysis.fragmenter.html#pymatgen.analysis.fragmenter.Fragmenter">[docs]</a><span class="k">class</span> <span class="nc">Fragmenter</span><span class="p">(</span><span class="n">MSONable</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Molecule fragmenter class.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">molecule</span><span class="p">,</span> <span class="n">edges</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">open_rings</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">use_metal_edge_extender</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                 <span class="n">opt_steps</span><span class="o">=</span><span class="mi">10000</span><span class="p">,</span> <span class="n">prev_unique_frag_dict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">assume_previous_thoroughness</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Standard constructor for molecule fragmentation</span>

<span class="sd">        Args:</span>
<span class="sd">            molecule (Molecule): The molecule to fragment.</span>
<span class="sd">            edges (list): List of index pairs that define graph edges, aka molecule bonds. If not set,</span>
<span class="sd">                edges will be determined with OpenBabel. Defaults to None.</span>
<span class="sd">            depth (int): The number of levels of iterative fragmentation to perform, where each level</span>
<span class="sd">                will include fragments obtained by breaking one bond of a fragment one level up.</span>
<span class="sd">                Defaults to 1. However, if set to 0, instead all possible fragments are generated</span>
<span class="sd">                using an alternative, non-iterative scheme.</span>
<span class="sd">            open_rings (bool): Whether or not to open any rings encountered during fragmentation.</span>
<span class="sd">                Defaults to False. If true, any bond that fails to yield disconnected graphs when</span>
<span class="sd">                broken is instead removed and the entire structure is optimized with OpenBabel in</span>
<span class="sd">                order to obtain a good initial guess for an opened geometry that can then be put</span>
<span class="sd">                back into QChem to be optimized without the ring just reforming.</span>
<span class="sd">            use_metal_edge_extender (bool): Whether or not to attempt to add additional edges from</span>
<span class="sd">                O, N, F, or Cl to any Li or Mg atoms present that OpenBabel may have missed. Defaults</span>
<span class="sd">                to False. Most important for ionic bonding. Note that additional metal edges may yield</span>
<span class="sd">                new &quot;rings&quot; (e.g. -C-O-Li-O- in LiEC) that will not play nicely with ring opening.</span>
<span class="sd">            opt_steps (int): Number of optimization steps when opening rings. Defaults to 10000.</span>
<span class="sd">            prev_unique_frag_dict (dict): A dictionary of previously identified unique fragments.</span>
<span class="sd">                Defaults to None. Typically only used when trying to find the set of unique fragments</span>
<span class="sd">                that come from multiple molecules.</span>
<span class="sd">            assume_previous_thoroughness (bool): Whether or not to assume that a molecule / fragment</span>
<span class="sd">                provided in prev_unique_frag_dict has all of its unique subfragments also provided in</span>
<span class="sd">                prev_unique_frag_dict. Defaults to True. This is an essential optimization when trying</span>
<span class="sd">                to find the set of unique fragments that come from multiple molecules if all of those</span>
<span class="sd">                molecules are being fully iteratively fragmented. However, if you&#39;re passing a</span>
<span class="sd">                prev_unique_frag_dict which includes a molecule and its fragments that were generated</span>
<span class="sd">                at insufficient depth to find all possible subfragments to a fragmentation calculation</span>
<span class="sd">                of a different molecule that you aim to find all possible subfragments of and which has</span>
<span class="sd">                common subfragments with the previous molecule, this optimization will cause you to</span>
<span class="sd">                miss some unique subfragments.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">assume_previous_thoroughness</span> <span class="o">=</span> <span class="n">assume_previous_thoroughness</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">open_rings</span> <span class="o">=</span> <span class="n">open_rings</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">opt_steps</span> <span class="o">=</span> <span class="n">opt_steps</span>

        <span class="k">if</span> <span class="n">edges</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span> <span class="o">=</span> <span class="n">MoleculeGraph</span><span class="o">.</span><span class="n">with_local_env_strategy</span><span class="p">(</span><span class="n">molecule</span><span class="p">,</span> <span class="n">OpenBabelNN</span><span class="p">())</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">edges</span> <span class="o">=</span> <span class="p">{(</span><span class="n">e</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">e</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span> <span class="kc">None</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">edges</span><span class="p">}</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span> <span class="o">=</span> <span class="n">MoleculeGraph</span><span class="o">.</span><span class="n">with_edges</span><span class="p">(</span><span class="n">molecule</span><span class="p">,</span> <span class="n">edges</span><span class="p">)</span>

        <span class="k">if</span> <span class="p">(</span><span class="s2">&quot;Li&quot;</span> <span class="ow">in</span> <span class="n">molecule</span><span class="o">.</span><span class="n">composition</span> <span class="ow">or</span> <span class="s2">&quot;Mg&quot;</span> <span class="ow">in</span> <span class="n">molecule</span><span class="o">.</span><span class="n">composition</span><span class="p">)</span> <span class="ow">and</span> <span class="n">use_metal_edge_extender</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span> <span class="o">=</span> <span class="n">metal_edge_extender</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span> <span class="o">=</span> <span class="n">prev_unique_frag_dict</span> <span class="ow">or</span> <span class="p">{}</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span> <span class="o">=</span> <span class="p">{}</span>  <span class="c1"># new fragments from the given molecule not contained in prev_unique_frag_dict</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span> <span class="o">=</span> <span class="p">{}</span>  <span class="c1"># all fragments from just the given molecule</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">unique_frag_dict</span> <span class="o">=</span> <span class="p">{}</span>  <span class="c1"># all fragments from both the given molecule and prev_unique_frag_dict</span>

        <span class="k">if</span> <span class="n">depth</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>  <span class="c1"># Non-iterative, find all possible fragments:</span>

            <span class="c1"># Find all unique fragments besides those involving ring opening</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">build_unique_fragments</span><span class="p">()</span>

            <span class="c1"># Then, if self.open_rings is True, open all rings present in self.unique_fragments</span>
            <span class="c1"># in order to capture all unique fragments that require ring opening.</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_rings</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">_open_all_rings</span><span class="p">()</span>

        <span class="k">else</span><span class="p">:</span>  <span class="c1"># Iterative fragment generation:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">fragments_by_level</span> <span class="o">=</span> <span class="p">{}</span>

            <span class="c1"># Loop through the number of levels,</span>
            <span class="k">for</span> <span class="n">level</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">depth</span><span class="p">):</span>
                <span class="c1"># If on the first level, perform one level of fragmentation on the principle molecule graph:</span>
                <span class="k">if</span> <span class="n">level</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">fragments_by_level</span><span class="p">[</span><span class="s2">&quot;0&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fragment_one_level</span><span class="p">({</span><span class="nb">str</span><span class="p">(</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">molecule</span><span class="o">.</span><span class="n">composition</span><span class="o">.</span><span class="n">alphabetical_formula</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot; E&quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span>
                        <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">edges</span><span class="p">())):</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span><span class="p">]})</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">num_frags_prev_level</span> <span class="o">=</span> <span class="mi">0</span>
                    <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">fragments_by_level</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">level</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)]:</span>
                        <span class="n">num_frags_prev_level</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fragments_by_level</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">level</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)][</span><span class="n">key</span><span class="p">])</span>
                    <span class="k">if</span> <span class="n">num_frags_prev_level</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                        <span class="c1"># Nothing left to fragment, so exit the loop:</span>
                        <span class="k">break</span>
                    <span class="k">else</span><span class="p">:</span>  <span class="c1"># If not on the first level, and there are fragments present in the previous level, then</span>
                        <span class="c1"># perform one level of fragmentation on all fragments present in the previous level:</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">fragments_by_level</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">level</span><span class="p">)]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fragment_one_level</span><span class="p">(</span>
                            <span class="bp">self</span><span class="o">.</span><span class="n">fragments_by_level</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">level</span><span class="o">-</span><span class="mi">1</span><span class="p">)])</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span> <span class="o">==</span> <span class="p">{}:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">frag_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">frag_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">])</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">for</span> <span class="n">fragment</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]:</span>
                        <span class="n">found</span> <span class="o">=</span> <span class="kc">False</span>
                        <span class="k">for</span> <span class="n">prev_frag</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]:</span>
                            <span class="k">if</span> <span class="n">fragment</span><span class="o">.</span><span class="n">isomorphic_to</span><span class="p">(</span><span class="n">prev_frag</span><span class="p">):</span>
                                <span class="n">found</span> <span class="o">=</span> <span class="kc">True</span>
                        <span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span>
                            <span class="k">if</span> <span class="n">frag_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">:</span>
                                <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">fragment</span><span class="p">]</span>
                            <span class="k">else</span><span class="p">:</span>
                                <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fragment</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_fragments</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">for</span> <span class="n">frag_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_fragments</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">])</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span> <span class="o">==</span> <span class="p">{}:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">unique_frag_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">total_unique_fragments</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_fragments</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">unique_frag_dict</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">frag_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">frag_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">unique_frag_dict</span><span class="p">:</span>
                    <span class="k">for</span> <span class="n">new_frag</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]:</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_frag</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">new_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">])</span>

            <span class="bp">self</span><span class="o">.</span><span class="n">total_unique_fragments</span> <span class="o">=</span> <span class="mi">0</span>
            <span class="k">for</span> <span class="n">frag_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">unique_frag_dict</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">total_unique_fragments</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">])</span>

    <span class="k">def</span> <span class="nf">_fragment_one_level</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_frag_dict</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Perform one step of iterative fragmentation on a list of molecule graphs. Loop through the graphs,</span>
<span class="sd">        then loop through each graph&#39;s edges and attempt to remove that edge in order to obtain two</span>
<span class="sd">        disconnected subgraphs, aka two new fragments. If successful, check to see if the new fragments</span>
<span class="sd">        are already present in self.unique_fragments, and append them if not. If unsucessful, we know</span>
<span class="sd">        that edge belongs to a ring. If we are opening rings, do so with that bond, and then again</span>
<span class="sd">        check if the resulting fragment is present in self.unique_fragments and add it if it is not.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">new_frag_dict</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">for</span> <span class="n">old_frag_key</span> <span class="ow">in</span> <span class="n">old_frag_dict</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">old_frag</span> <span class="ow">in</span> <span class="n">old_frag_dict</span><span class="p">[</span><span class="n">old_frag_key</span><span class="p">]:</span>
                <span class="k">for</span> <span class="n">edge</span> <span class="ow">in</span> <span class="n">old_frag</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">edges</span><span class="p">:</span>
                    <span class="n">bond</span> <span class="o">=</span> <span class="p">[(</span><span class="n">edge</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">edge</span><span class="p">[</span><span class="mi">1</span><span class="p">])]</span>
                    <span class="n">fragments</span> <span class="o">=</span> <span class="p">[]</span>
                    <span class="k">try</span><span class="p">:</span>
                        <span class="n">fragments</span> <span class="o">=</span> <span class="n">old_frag</span><span class="o">.</span><span class="n">split_molecule_subgraphs</span><span class="p">(</span><span class="n">bond</span><span class="p">,</span> <span class="n">allow_reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
                    <span class="k">except</span> <span class="n">MolGraphSplitError</span><span class="p">:</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_rings</span><span class="p">:</span>
                            <span class="n">fragments</span> <span class="o">=</span> <span class="p">[</span><span class="n">open_ring</span><span class="p">(</span><span class="n">old_frag</span><span class="p">,</span> <span class="n">bond</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">opt_steps</span><span class="p">)]</span>
                    <span class="k">for</span> <span class="n">fragment</span> <span class="ow">in</span> <span class="n">fragments</span><span class="p">:</span>
                        <span class="n">new_frag_key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">fragment</span><span class="o">.</span><span class="n">molecule</span><span class="o">.</span><span class="n">composition</span><span class="o">.</span><span class="n">alphabetical_formula</span><span class="p">)</span><span class="o">+</span><span class="s2">&quot; E&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span>
                            <span class="nb">len</span><span class="p">(</span><span class="n">fragment</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">edges</span><span class="p">()))</span>
                        <span class="n">proceed</span> <span class="o">=</span> <span class="kc">True</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">assume_previous_thoroughness</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span> <span class="o">!=</span> <span class="p">{}:</span>
                            <span class="k">if</span> <span class="n">new_frag_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span><span class="p">:</span>
                                <span class="k">for</span> <span class="n">unique_fragment</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">prev_unique_frag_dict</span><span class="p">[</span><span class="n">new_frag_key</span><span class="p">]:</span>
                                    <span class="k">if</span> <span class="n">unique_fragment</span><span class="o">.</span><span class="n">isomorphic_to</span><span class="p">(</span><span class="n">fragment</span><span class="p">):</span>
                                        <span class="n">proceed</span> <span class="o">=</span> <span class="kc">False</span>
                                        <span class="k">break</span>
                        <span class="k">if</span> <span class="n">proceed</span><span class="p">:</span>
                            <span class="k">if</span> <span class="n">new_frag_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">:</span>
                                <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">new_frag_key</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">fragment</span><span class="p">]</span>
                                <span class="n">new_frag_dict</span><span class="p">[</span><span class="n">new_frag_key</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">fragment</span><span class="p">]</span>
                            <span class="k">else</span><span class="p">:</span>
                                <span class="n">found</span> <span class="o">=</span> <span class="kc">False</span>
                                <span class="k">for</span> <span class="n">unique_fragment</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">new_frag_key</span><span class="p">]:</span>
                                    <span class="k">if</span> <span class="n">unique_fragment</span><span class="o">.</span><span class="n">isomorphic_to</span><span class="p">(</span><span class="n">fragment</span><span class="p">):</span>
                                        <span class="n">found</span> <span class="o">=</span> <span class="kc">True</span>
                                        <span class="k">break</span>
                                <span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">new_frag_key</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fragment</span><span class="p">)</span>
                                    <span class="k">if</span> <span class="n">new_frag_key</span> <span class="ow">in</span> <span class="n">new_frag_dict</span><span class="p">:</span>
                                        <span class="n">new_frag_dict</span><span class="p">[</span><span class="n">new_frag_key</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fragment</span><span class="p">)</span>
                                    <span class="k">else</span><span class="p">:</span>
                                        <span class="n">new_frag_dict</span><span class="p">[</span><span class="n">new_frag_key</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">fragment</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">new_frag_dict</span>

    <span class="k">def</span> <span class="nf">_open_all_rings</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Having already generated all unique fragments that did not require ring opening,</span>
<span class="sd">        now we want to also obtain fragments that do require opening. We achieve this by</span>
<span class="sd">        looping through all unique fragments and opening each bond present in any ring</span>
<span class="sd">        we find. We also temporarily add the principle molecule graph to self.unique_fragments</span>
<span class="sd">        so that its rings are opened as well.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">mol_key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">molecule</span><span class="o">.</span><span class="n">composition</span><span class="o">.</span><span class="n">alphabetical_formula</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot; E&quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span>
            <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">edges</span><span class="p">()))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">mol_key</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">mol_graph</span><span class="p">]</span>
        <span class="n">new_frag_keys</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;0&quot;</span><span class="p">:</span> <span class="p">[]}</span>
        <span class="n">new_frag_key_dict</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">fragment</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]:</span>
                <span class="n">ring_edges</span> <span class="o">=</span> <span class="n">fragment</span><span class="o">.</span><span class="n">find_rings</span><span class="p">()</span>
                <span class="k">if</span> <span class="n">ring_edges</span> <span class="o">!=</span> <span class="p">[]:</span>
                    <span class="k">for</span> <span class="n">bond</span> <span class="ow">in</span> <span class="n">ring_edges</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
                        <span class="n">new_fragment</span> <span class="o">=</span> <span class="n">open_ring</span><span class="p">(</span><span class="n">fragment</span><span class="p">,</span> <span class="p">[</span><span class="n">bond</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">opt_steps</span><span class="p">)</span>
                        <span class="n">frag_key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">new_fragment</span><span class="o">.</span><span class="n">molecule</span><span class="o">.</span><span class="n">composition</span><span class="o">.</span><span class="n">alphabetical_formula</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot; E&quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span>
                            <span class="nb">len</span><span class="p">(</span><span class="n">new_fragment</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">edges</span><span class="p">()))</span>
                        <span class="k">if</span> <span class="n">frag_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">:</span>
                            <span class="k">if</span> <span class="n">frag_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">new_frag_keys</span><span class="p">[</span><span class="s2">&quot;0&quot;</span><span class="p">]:</span>
                                <span class="n">new_frag_keys</span><span class="p">[</span><span class="s2">&quot;0&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">frag_key</span><span class="p">))</span>
                                <span class="n">new_frag_key_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">([</span><span class="n">new_fragment</span><span class="p">])</span>
                            <span class="k">else</span><span class="p">:</span>
                                <span class="n">found</span> <span class="o">=</span> <span class="kc">False</span>
                                <span class="k">for</span> <span class="n">unique_fragment</span> <span class="ow">in</span> <span class="n">new_frag_key_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]:</span>
                                    <span class="k">if</span> <span class="n">unique_fragment</span><span class="o">.</span><span class="n">isomorphic_to</span><span class="p">(</span><span class="n">new_fragment</span><span class="p">):</span>
                                        <span class="n">found</span> <span class="o">=</span> <span class="kc">True</span>
                                        <span class="k">break</span>
                                <span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span>
                                    <span class="n">new_frag_key_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">new_fragment</span><span class="p">))</span>
                        <span class="k">else</span><span class="p">:</span>
                            <span class="n">found</span> <span class="o">=</span> <span class="kc">False</span>
                            <span class="k">for</span> <span class="n">unique_fragment</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]:</span>
                                <span class="k">if</span> <span class="n">unique_fragment</span><span class="o">.</span><span class="n">isomorphic_to</span><span class="p">(</span><span class="n">new_fragment</span><span class="p">):</span>
                                    <span class="n">found</span> <span class="o">=</span> <span class="kc">True</span>
                                    <span class="k">break</span>
                            <span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span>
                                <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">new_fragment</span><span class="p">))</span>
        <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">new_frag_key_dict</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">new_frag_key_dict</span><span class="p">[</span><span class="n">key</span><span class="p">])</span>
        <span class="n">idx</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">new_frag_keys</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">)])</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">new_frag_key_dict</span> <span class="o">=</span> <span class="p">{}</span>
            <span class="n">idx</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="n">new_frag_keys</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">)]</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">new_frag_keys</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)]:</span>
                <span class="k">for</span> <span class="n">fragment</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]:</span>
                    <span class="n">ring_edges</span> <span class="o">=</span> <span class="n">fragment</span><span class="o">.</span><span class="n">find_rings</span><span class="p">()</span>
                    <span class="k">if</span> <span class="n">ring_edges</span> <span class="o">!=</span> <span class="p">[]:</span>
                        <span class="k">for</span> <span class="n">bond</span> <span class="ow">in</span> <span class="n">ring_edges</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
                            <span class="n">new_fragment</span> <span class="o">=</span> <span class="n">open_ring</span><span class="p">(</span><span class="n">fragment</span><span class="p">,</span> <span class="p">[</span><span class="n">bond</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">opt_steps</span><span class="p">)</span>
                            <span class="n">frag_key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">new_fragment</span><span class="o">.</span><span class="n">molecule</span><span class="o">.</span><span class="n">composition</span><span class="o">.</span><span class="n">alphabetical_formula</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot; E&quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span>
                                <span class="nb">len</span><span class="p">(</span><span class="n">new_fragment</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">edges</span><span class="p">()))</span>
                            <span class="k">if</span> <span class="n">frag_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">:</span>
                                <span class="k">if</span> <span class="n">frag_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">new_frag_keys</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">)]:</span>
                                    <span class="n">new_frag_keys</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">)]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">frag_key</span><span class="p">))</span>
                                    <span class="n">new_frag_key_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">([</span><span class="n">new_fragment</span><span class="p">])</span>
                                <span class="k">else</span><span class="p">:</span>
                                    <span class="n">found</span> <span class="o">=</span> <span class="kc">False</span>
                                    <span class="k">for</span> <span class="n">unique_fragment</span> <span class="ow">in</span> <span class="n">new_frag_key_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]:</span>
                                        <span class="k">if</span> <span class="n">unique_fragment</span><span class="o">.</span><span class="n">isomorphic_to</span><span class="p">(</span><span class="n">new_fragment</span><span class="p">):</span>
                                            <span class="n">found</span> <span class="o">=</span> <span class="kc">True</span>
                                            <span class="k">break</span>
                                    <span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span>
                                        <span class="n">new_frag_key_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">new_fragment</span><span class="p">))</span>
                            <span class="k">else</span><span class="p">:</span>
                                <span class="n">found</span> <span class="o">=</span> <span class="kc">False</span>
                                <span class="k">for</span> <span class="n">unique_fragment</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]:</span>
                                    <span class="k">if</span> <span class="n">unique_fragment</span><span class="o">.</span><span class="n">isomorphic_to</span><span class="p">(</span><span class="n">new_fragment</span><span class="p">):</span>
                                        <span class="n">found</span> <span class="o">=</span> <span class="kc">True</span>
                                        <span class="k">break</span>
                                <span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">frag_key</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">new_fragment</span><span class="p">))</span>
            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">new_frag_key_dict</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">new_frag_key_dict</span><span class="p">[</span><span class="n">key</span><span class="p">])</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">all_unique_frag_dict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">mol_key</span><span class="p">)</span></div>


<div class="viewcode-block" id="open_ring"><a class="viewcode-back" href="../../../pymatgen.analysis.fragmenter.html#pymatgen.analysis.fragmenter.open_ring">[docs]</a><span class="k">def</span> <span class="nf">open_ring</span><span class="p">(</span><span class="n">mol_graph</span><span class="p">,</span> <span class="n">bond</span><span class="p">,</span> <span class="n">opt_steps</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Function to actually open a ring using OpenBabel&#39;s local opt. Given a molecule</span>
<span class="sd">    graph and a bond, convert the molecule graph into an OpenBabel molecule, remove</span>
<span class="sd">    the given bond, perform the local opt with the number of steps determined by</span>
<span class="sd">    self.steps, and then convert the resulting structure back into a molecule graph</span>
<span class="sd">    to be returned.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">obmol</span> <span class="o">=</span> <span class="n">BabelMolAdaptor</span><span class="o">.</span><span class="n">from_molecule_graph</span><span class="p">(</span><span class="n">mol_graph</span><span class="p">)</span>
    <span class="n">obmol</span><span class="o">.</span><span class="n">remove_bond</span><span class="p">(</span><span class="n">bond</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">bond</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
    <span class="n">obmol</span><span class="o">.</span><span class="n">localopt</span><span class="p">(</span><span class="n">steps</span><span class="o">=</span><span class="n">opt_steps</span><span class="p">,</span> <span class="n">forcefield</span><span class="o">=</span><span class="s1">&#39;uff&#39;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">MoleculeGraph</span><span class="o">.</span><span class="n">with_local_env_strategy</span><span class="p">(</span><span class="n">obmol</span><span class="o">.</span><span class="n">pymatgen_mol</span><span class="p">,</span> <span class="n">OpenBabelNN</span><span class="p">())</span></div>


<div class="viewcode-block" id="metal_edge_extender"><a class="viewcode-back" href="../../../pymatgen.analysis.fragmenter.html#pymatgen.analysis.fragmenter.metal_edge_extender">[docs]</a><span class="k">def</span> <span class="nf">metal_edge_extender</span><span class="p">(</span><span class="n">mol_graph</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Function to identify and add missed edges in ionic bonding of Li and Mg ions.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">metal_sites</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;Li&quot;</span><span class="p">:</span> <span class="p">{},</span> <span class="s2">&quot;Mg&quot;</span><span class="p">:</span> <span class="p">{}}</span>
    <span class="n">coordinators</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;O&quot;</span><span class="p">,</span> <span class="s2">&quot;N&quot;</span><span class="p">,</span> <span class="s2">&quot;F&quot;</span><span class="p">,</span> <span class="s2">&quot;Cl&quot;</span><span class="p">]</span>
    <span class="n">num_new_edges</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">idx</span> <span class="ow">in</span> <span class="n">mol_graph</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">nodes</span><span class="p">():</span>
        <span class="k">if</span> <span class="n">mol_graph</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">nodes</span><span class="p">()[</span><span class="n">idx</span><span class="p">][</span><span class="s2">&quot;specie&quot;</span><span class="p">]</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">:</span>
            <span class="n">metal_sites</span><span class="p">[</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">graph</span><span class="o">.</span><span class="n">nodes</span><span class="p">()[</span><span class="n">idx</span><span class="p">][</span><span class="s2">&quot;specie&quot;</span><span class="p">]][</span><span class="n">idx</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">site</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">for</span> <span class="n">site</span> <span class="ow">in</span>
                                                                        <span class="n">mol_graph</span><span class="o">.</span><span class="n">get_connected_sites</span><span class="p">(</span><span class="n">idx</span><span class="p">)]</span>
    <span class="k">for</span> <span class="n">metal</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">idx</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">]:</span>
            <span class="k">for</span> <span class="n">ii</span><span class="p">,</span> <span class="n">site</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">molecule</span><span class="p">):</span>
                <span class="k">if</span> <span class="n">ii</span> <span class="o">!=</span> <span class="n">idx</span> <span class="ow">and</span> <span class="n">ii</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">][</span><span class="n">idx</span><span class="p">]:</span>
                    <span class="k">if</span> <span class="nb">str</span><span class="p">(</span><span class="n">site</span><span class="o">.</span><span class="n">specie</span><span class="p">)</span> <span class="ow">in</span> <span class="n">coordinators</span><span class="p">:</span>
                        <span class="k">if</span> <span class="n">site</span><span class="o">.</span><span class="n">distance</span><span class="p">(</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">molecule</span><span class="p">[</span><span class="n">idx</span><span class="p">])</span> <span class="o">&lt;</span> <span class="mf">2.5</span><span class="p">:</span>
                            <span class="n">mol_graph</span><span class="o">.</span><span class="n">add_edge</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">ii</span><span class="p">)</span>
                            <span class="n">num_new_edges</span> <span class="o">+=</span> <span class="mi">1</span>
                            <span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">][</span><span class="n">idx</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">ii</span><span class="p">)</span>
    <span class="n">total_metal_edges</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">metal</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">idx</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">]:</span>
            <span class="n">total_metal_edges</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">][</span><span class="n">idx</span><span class="p">])</span>
    <span class="k">if</span> <span class="n">total_metal_edges</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">metal</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">idx</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">]:</span>
                <span class="k">for</span> <span class="n">ii</span><span class="p">,</span> <span class="n">site</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">molecule</span><span class="p">):</span>
                    <span class="k">if</span> <span class="n">ii</span> <span class="o">!=</span> <span class="n">idx</span> <span class="ow">and</span> <span class="n">ii</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">][</span><span class="n">idx</span><span class="p">]:</span>
                        <span class="k">if</span> <span class="nb">str</span><span class="p">(</span><span class="n">site</span><span class="o">.</span><span class="n">specie</span><span class="p">)</span> <span class="ow">in</span> <span class="n">coordinators</span><span class="p">:</span>
                            <span class="k">if</span> <span class="n">site</span><span class="o">.</span><span class="n">distance</span><span class="p">(</span><span class="n">mol_graph</span><span class="o">.</span><span class="n">molecule</span><span class="p">[</span><span class="n">idx</span><span class="p">])</span> <span class="o">&lt;</span> <span class="mf">3.5</span><span class="p">:</span>
                                <span class="n">mol_graph</span><span class="o">.</span><span class="n">add_edge</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">ii</span><span class="p">)</span>
                                <span class="n">num_new_edges</span> <span class="o">+=</span> <span class="mi">1</span>
                                <span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">][</span><span class="n">idx</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">ii</span><span class="p">)</span>
    <span class="n">total_metal_edges</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">metal</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">idx</span> <span class="ow">in</span> <span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">]:</span>
            <span class="n">total_metal_edges</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">metal_sites</span><span class="p">[</span><span class="n">metal</span><span class="p">][</span><span class="n">idx</span><span class="p">])</span>
    <span class="k">return</span> <span class="n">mol_graph</span></div>
</pre></div>

            <div class="clearer"></div>
          </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">pymatgen 2020.7.3 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../../pymatgen.html" >pymatgen</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">pymatgen.analysis.fragmenter</a></li> 
      </ul>
    </div>

    <div class="footer" role="contentinfo">
        &#169; Copyright 2011, Pymatgen Development Team.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.2.
    </div>
<div class="footer">This page uses <a href="http://analytics.google.com/">
Google Analytics</a> to collect statistics. You can disable it by blocking
the JavaScript coming from www.google-analytics.com.
<script type="text/javascript">
  (function() {
    var ga = document.createElement('script');
    ga.src = ('https:' == document.location.protocol ?
              'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    ga.setAttribute('async', 'true');
    document.documentElement.firstChild.appendChild(ga);
  })();
</script>
</div>

  </body>
</html>